package com.lzw.main;

import com.lzw.app.Instance;
import com.lzw.property.LzwProperties;
import com.lzw.property.ServerProperties;

import java.io.*;
import java.net.Socket;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * PING-PONG线程
 *      服务/集群的续约
 * @author LZW
 */
public class PingPongThread implements Runnable {
    private LzwProperties lzwProperties;
    private final String ip_self;
    private final int port_self;
    private final int invalidateTime;
    private ThreadPoolExecutor poolExecutor;


    public PingPongThread(LzwProperties lzwProperties, ServerProperties serverProperties, ThreadPoolExecutor poolExecutor) {
        this.lzwProperties = lzwProperties;
        this.ip_self = serverProperties.getIp();
        this.port_self = serverProperties.getPort();
        this.invalidateTime = lzwProperties.getInvalidateTime();
        this.poolExecutor = poolExecutor;
    }

    public void run() {
        final int interval = lzwProperties.getPingInterval();
        List<String> serverIpPort = lzwProperties.getServerIpPort();
        while (true) {
            try {
                Thread.sleep(interval * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (serverIpPort == null || serverIpPort.size() == 0) {
                return;
            }
            for (String ipPort : serverIpPort) {
                final String[] split = ipPort.split(":");
                final String ip = split[0];
                final int port = Integer.parseInt(split[1]);
                //调用线程池，执行续约
                poolExecutor.execute(new Runnable() {
                    public void run() {
                        try {
                            Socket socket = new Socket(ip, port);
                            OutputStream outputStream = socket.getOutputStream();
                            InputStream inputStream = socket.getInputStream();
                            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream));
                            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
                            //传递action信息
                            bw.write("ping");
                            bw.newLine();
                            bw.flush();
                            //接收response信息
                            String status = br.readLine();
                            if ("OK".equals(status)) {
                                ObjectOutputStream oos = new ObjectOutputStream(outputStream);
                                Instance instance = new Instance();
                                instance.setHost(ip_self);
                                instance.setPort(port_self);
                                String appName = lzwProperties.getAppName();
                                instance.setName(appName);
                                instance.setUrl("http://" + instance.getHost() + ":" + instance.getPort());
                                instance.setId(instance.getHost() + ":" + instance.getName() + ":" + instance.getPort());
                                instance.setInvalidateSecond(invalidateTime);
                                oos.writeObject(instance);
                                oos.flush();
                            }
                            String resp = br.readLine();
                            socket.close();
                        } catch (Exception e) {
                            System.out.println("超时：找不到注册中心服务器。。Ping失败！" + interval + "秒后重新尝试。。");
                        }
                    }
                });
            }
        }
    }
}
